/* global window */
import modelExtend from 'dva-model-extend'
import { config } from 'utils'
import * as deployService from '../services/deploy'
import { pageModel } from './common'
import * as systemProcessService from '../services/systemprocess'
import * as processtypeService from '../services/processtype'
import * as processconfigService from '../services/processconfig'

const { fetch } = deployService
const { prefix } = config

export default modelExtend(pageModel, {
  namespace: 'deploy',

  state: {
    currentItem: {},
    modalVisible: false,
    modalType: 'create',
    selectedRowKeys: [],
    isMotion: window.localStorage.getItem(`${prefix}deployIsMotion`) === 'true',
    file: {},
    systemProcessList: [],
    processTypeList: [],
    diagram: {},
    deploySelected: {},
    taskNodeList: [],
    taskNode: {},
    taskModalVisible: false,
    approveTypeCheckedValue: false,
    jobTreeData: [],
    accountTreeData: [],
    systemCode: '',
  },

  subscriptions: {
    setup ({ dispatch, history }) {
      history.listen((location) => {
        if (location.pathname === '/deploy') {
          const payload = location.query || { current: 1, pageSize: 10 }
          dispatch({
            type: 'query',
            payload,
          })
          dispatch({
            type: 'setTaskNodeList',
            payload: [],
          })
          dispatch({
            type: 'deploySelected',
            payload: {},
          })
        }
      })
    },
  },

  effects: {
    * query ({ payload = {} }, { call, put, select }) {
      if (payload.systemCode || payload.systemCode === '') {
        yield put({
          type: 'updateSearch',
          payload: payload.systemCode,
        })
      } else {
        const systemCode = yield select(({ deploy }) => deploy.systemCode)
        payload.systemCode = systemCode
      }
      const data = yield call(fetch, payload)
      if (data) {
        yield put({
          type: 'querySuccess',
          payload: {
            list: data.data.list,
            pagination: {
              current: Number(payload.page) || 1,
              pageSize: Number(payload.pageSize) || 10,
              total: data.data.total,
              showSizeChanger: false,
            },
          },
        })
      }
      const listSystemProcess = yield call(systemProcessService.list)
      if (listSystemProcess) {
        yield put({
          type: 'setListSystemProcess',
          payload: listSystemProcess.data,
        })
      }
    },
    * reloadSelection ({ payload }, { call, put, select }) {
      const listSystemProcess = yield call(systemProcessService.list)
      if (listSystemProcess) {
        yield put({
          type: 'setListSystemProcess',
          payload: listSystemProcess.data,
        })
      }
    },
    * delete ({ payload }, { call, put, select }) {
      const data = yield call(deployService.remove, { id: payload })
      const { selectedRowKeys } = yield select(_ => _.deploy)
      if (data.success) {
        yield put({ type: 'updateState', payload: { selectedRowKeys: selectedRowKeys.filter(_ => _ !== payload) } })
        yield put({ type: 'query' })
      } else {
        throw data
      }
    },

    * multiDelete ({ payload }, { call, put }) {
      const data = yield call(deployService.remove, payload)
      if (data.success) {
        yield put({ type: 'updateState', payload: { selectedRowKeys: [] } })
        yield put({ type: 'query' })
      } else {
        throw data
      }
    },

    * create ({ payload }, { call, put }) {
      const data = yield call(deployService.create, payload)
      if (data.success) {
        yield put({ type: 'hideModal' })
        yield put({ type: 'query' })
      } else {
        throw data
      }
    },
    * deploy ({ payload }, { call, put }) {
      console.log(payload)
      const data = yield call(deployService.deployProcess, payload)
      if (data.data.code === 200) {
        yield put({ type: 'hideModal' })
        yield put({ type: 'query' })
      } else if (data.data.code === 400) {
        throw new Error(data.message)
      }
    },

    * update ({ payload }, { select, call, put }) {
      const id = yield select(({ deploy }) => deploy.currentItem.id)
      const newDeploy = { ...payload, id }
      const data = yield call(deployService.patch, newDeploy)
      if (data.success) {
        yield put({ type: 'hideModal' })
        yield put({ type: 'query' })
      } else {
        throw data
      }
    },

    * uploadFile ({ payload }, { call, put }) {
      const { file } = payload
      const _file = file[0]
      let formData = new FormData()
      formData.append('file', _file)
      formData.append('systemCode', payload.processType[0])
      formData.append('processTypeId', payload.processType[1])

      try {
        const result = yield call(deployService.deployProcess, formData)
      } catch (e) {
        throw e
      }
      // console.log()
      // console.log(_file)
    },

    * listSystemProcess ({ call, select }) {
      const { data } = yield call(systemProcessService.list)
      yield select(state => state.systemProcessList)
    },
    * listProcessType ({ payload }, { call, put }) {
      let param = { systemCode: payload[0].label }
      const result = yield call(processtypeService.listNoPage, param)
      if (result) {
        yield put({
          type: 'setListProcessType',
          payload: { selectedOption: payload, children: result.data },
        })
      }
    },
    * deploySelected ({ payload }, { call, put }) {
      let result = yield call(processconfigService.fetch, payload)
      if (result) {
        yield put({
          type: 'setTaskNodeList',
          payload: result.data,
        })
        yield put({
          type: 'setSelectDeloy',
          payload,
        })
      }
    },
    * taskNodeConfig ({ payload }, { call, put }) {
      yield put({
        type: 'setTaskNode',
        payload,
      })
      const result = yield call(processconfigService.fetchJobTree)
      if (result) {
        yield put({
          type: 'setJobTreeData',
          payload: result.data,
        })
      }
      const _result = yield call(processconfigService.fetchAccountTree)
      if (_result) {
        yield put({
          type: 'setAccountTreeData',
          payload: _result.data,
        })
      }
    },
    * clickStartTaskNode ({ payload }, { call, put, select }) {
      const result = yield call(processconfigService.startTaskNode, payload)
      if (result) {
        const taskClickNode = yield select(({ deploy }) => deploy.deploySelected)
        let _result = yield call(processconfigService.fetch, taskClickNode)
        if (_result) {
          yield put({
            type: 'setTaskNodeList',
            payload: _result.data,
          })
          yield put({
            type: 'setSelectDeloy',
            payload: taskClickNode,
          })
        }
      }
    },
    * configTaskNode ({ payload }, { call, put, select }) {
      const taskNode = yield select(({ deploy }) => deploy.taskNode.id)
      const taskClickNode = yield select(({ deploy }) => deploy.deploySelected)
      const updateTaskNode = { ...payload, taskNode }
      const result = yield call(processconfigService.update, updateTaskNode)
      if (result) {
        yield put({
          type: 'hideTaskNodeModal',
        })
      }
      yield put({
        type: 'deploySelected',
        payload: taskClickNode,
      })
    },

    * showModal ({ payload }, { call, put, select }) {
      const { data } = yield call(systemProcessService.systemprocessNameList)
      if (data) {
        yield put({
          type: 'showModalData',
          payload: data,
        })
      }
    },
    * selectProcessTypeBySystemSelect ({ payload }, { call, put, select }) {
      const { data } = yield call(processtypeService.processTypeBySystemSelect, payload)
      if (data) {
        yield put({
          type: 'updateProcessTypeList',
          payload: data.data,
        })
      }
    },
  },

  reducers: {
    setSelectDeloy (state, { payload }) {
      return { ...state, deploySelected: payload }
    },
    updateProcessTypeList (state, { payload }) {
      return { ...state, processTypeList: payload }
    },
    updateSearch (state, { payload }) {
      return { ...state, ...payload, systemCode: payload }
    },
    showModalData (state, { payload }) {
      return { ...state, systemProcessList: payload, modalVisible: true }
    },
    onPopupVisibleChange (state, { payload }) {
      return { ...state, systemProcessList: [] }
    },
    hideModal (state) {
      return { ...state, modalVisible: false, selectedOption: [], processTypeList: [] }
    },
    hideTaskNodeModal (state) {
      return { ...state, taskModalVisible: false, selectedOption: [], approveTypeCheckedValue: false }
    },

    switchIsMotion (state) {
      window.localStorage.setItem(`${prefix}deployIsMotion`, !state.isMotion)
      return { ...state, isMotion: !state.isMotion }
    },

    beforeUpload (state, { payload }) {
      return { ...state, ...payload, file: payload }
    },

    deleteUpload (state, { payload }) {
      return { ...state, ...payload, file: {} }
    },

    setListSystemProcess (state, { payload }) {
      let result = payload.map((item) => {
        return {
          value: item.appId,
          label: item.appId,
          isLeaf: false,
        }
      })
      return { ...state, ...payload, systemProcessList: result }
    },
    setTaskNodeList (state, { payload }) {
      return { ...state, ...payload, taskNodeList: payload.data }
    },
    setListProcessType (state, { payload }) {
      let result = payload.children.data.map((item) => {
        return {
          value: item.id,
          label: item.bizName,
          isLeaf: true,
          loading: false,
        }
      })
      payload.selectedOption[0].children = result
      return { ...state, ...payload, systemProcessList: payload.selectedOption }
    },
    setTaskNode (state, { payload }) {
      return {
        ...state,
        ...payload,
        taskNode: payload,
        taskModalVisible: !state.taskModalVisible,
      }
    },
    setAccountTreeData (state, { payload }) {
      return {
        ...state,
        ...payload,
        accountTreeData: payload.data,
      }
    },
    setJobTreeData (state, { payload }) {
      return {
        ...state,
        ...payload,
        jobTreeData: payload.data,
      }
    },
    approveTypeChangeChecked (state, { payload }) {
      if (payload) { state.taskNode.approveType = 0 } else { state.taskNode.approveType = 1 }
      return {
        ...state,
        ...payload,
        approveTypeCheckedValue: !state.approveTypeCheckedValue,
      }
    },
  },
})
